package org.juggers.services;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.util.ArrayList;
import java.util.List;

import javax.persistence.NoResultException;

import org.juggers.component.MailSender;
import org.juggers.domain.AuthenticationException;
import org.juggers.domain.InvalidEmailException;
import org.juggers.domain.Jugger;
import org.juggers.domain.PendingException;
import org.juggers.domain.SendMailException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.annotation.Secured;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.stereotype.Service;

/**
 * @author <a href="mailto:michel@breizhjug.org">Michel DAVID</a>
 */
@Service
public class DefaultUserService
    implements UserService
{
    @Autowired
    private MailSender mailSender;

    @Override
    public Jugger login( String login, String password )
        throws PendingException, AuthenticationException
    {
        Jugger jugger = null;
        try
        {
            jugger = Jugger.findByEMail( login );
        }
        catch ( NoResultException ex )
        {
            throw new AuthenticationException();
        }

        if ( jugger.isPending() )
        {
            throw new PendingException();
        }

        if ( !password.equals( jugger.getPassword() ) )
        {
            throw new AuthenticationException();
        }

        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        for ( String role : jugger.getRoles() )
        {
            authorities.add( new GrantedAuthorityImpl( role ) );
        }

        Authentication authentication =
            new UsernamePasswordAuthenticationToken(
                                                     jugger,
                                                     jugger.getPassword(),
                                                     (GrantedAuthority[]) authorities.toArray( new GrantedAuthorityImpl[authorities.size()] ) );

        SecurityContextHolder.getContext().setAuthentication( authentication );

        return jugger;
    }

    @Override
    public void sendPassword( String email )
        throws InvalidEmailException, SendMailException
    {
        Jugger jugger = null;
        try
        {
            jugger = Jugger.findByEMail( email );
        }
        catch ( NoResultException ex )
        {
            throw new InvalidEmailException();
        }

        mailSender.send( "password", "Juggers.org: Votre mot de passe", jugger );
    }

    @Override
    @Secured( { "ROLE_JUGGER" } )
    public Jugger getConnectedUser()
    {
        try
        {
            return Jugger.findByEMail( SecurityContextHolder.getContext().getAuthentication().getName() );
        }
        catch ( NoResultException ex )
        {
            return null;
        }
    }

    @Override
    public String get( Long id )
    {
        try
        {
            Jugger jugger = Jugger.findById( id );
            return getUsername( jugger );
        }
        catch ( NoResultException ex )
        {
            return null;
        }
    }

    @Override
    public List<String> get( List<Long> ids )
    {
        List<String> users = new ArrayList<String>();
        for ( Long id : ids )
        {
            try
            {
                Jugger jugger = Jugger.findById( id );
                users.add( getUsername( jugger ) );
            }
            catch ( NoResultException ex )
            {

            }
        }
        return users;
    }

    private static String getUsername( Jugger jugger )
    {
        return jugger.getFirstName() + " " + jugger.getLastName();
    }
}
